package cn.mesmile.thread.jvm;

/**
 * @author zb
 * @date 2021/4/5 15:42
 * @Description:
 *
 *      * 栈上分配，标量替换
 *      * 代码调用了1亿次alloc()，如果是分配到堆上，大概需要1GB以上堆空间，如果堆空间小于该值，必然会触发GC。
 *      *
 *              DoEscapeAnalysis 逃逸分析     EliminateAllocations 标量替换
 *
 *              逃逸分析：在分配内存的时候，会先检查方法里面的对象是否会有返回，若没有返回则认为该对象不会逃逸这个方法，则将对象存放在【栈】中
 *              标量替换：首先要明白标量和聚合量，基础类型和对象的引用可以理解为标量，它们不能被进一步分解。而能被进一步分解的量就是聚合量，比如：对象。
 *              对象是聚合量，它又可以被进一步分解成标量，将其成员变量分解为分散的变量，这就叫做标量替换。 这样，如果一个对象没有发生逃逸，
 *              那压根就不用创建它，只会在栈或者寄存器上创建它用到的成员标量，节省了内存空间，也提升了应用程序性能。
 *              标量替换的 JVM 参数如下：
 *
 *              开启标量替换：-XX:+EliminateAllocations
 *              关闭标量替换：-XX:-EliminateAllocations
 *              显示标量替换详情：-XX:+PrintEliminateAllocations
 *
 *              标量替换同样在 JDK8 中都是默认开启的，并且都要建立在逃逸分析的基础上
 *
 *      * 使用如下参数不会发生GC
 *      * -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:+EliminateAllocations
 *      * 使用如下参数都会发生大量GC
 *      * -Xmx15m -Xms15m -XX:-DoEscapeAnalysis -XX:+PrintGC -XX:+EliminateAllocations
 *      * -Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-EliminateAllocations
 *
 */
public class AllotOnStack {

    public static void main(String[] args) {

        System.out.println("sdfaskldjf");
        for (int i = 0; i < 10000000; i++) {
            alloc();
        }

    }

    public static void alloc(){
        Student student = new Student();
        student.setUsername("test");
    }
}
